﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using AzureMLClient;
using AzureMLClient.Contracts;
using Newtonsoft.Json;
using WebGrease.Css.Extensions;

namespace WebApplicationDemo.Controllers
{
    public class HomeController : Controller
    {
        private IEnumerable<WebService> _webServices;

        public HomeController()
        {
            var client = new Client();
            this._webServices = client.GetWebServicesAsync().Result;
        }

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult SelectRetrainEndpoint()
        {
            // look for webservice with name 'train', and put it upfront
            this._webServices = this._webServices.OrderBy(w =>
            {
                if (w.Name.ToLower().Contains("train"))
                {
                    return 0;
                }

                return 1;
            });

            // then look for non-default endpoint and put it upfront
            this._webServices.ForEach(w =>
                w.Endpoints = w.Endpoints.OrderByDescending(e =>
                {
                    if (e.Name == w.DefaultEndpointName)
                    {
                        return 0;
                    }
                    return 1;
                })
                );

            ViewBag.WebServices = JsonConvert.SerializeObject(this._webServices);

            return View();
        }

        public ActionResult SelectScoringEndpoint()
        {
            // look for webservice with name 'scor', and put it upfront
            this._webServices = this._webServices.OrderBy(w =>
            {
                if (w.Name.ToLower().Contains("scor"))
                {
                    return 0;
                }

                return 1;
            });

            // then look for non-default endpoint and put it upfront
            this._webServices.ForEach(w =>
                w.Endpoints = w.Endpoints.OrderByDescending(e =>
                {
                    if (e.Name == w.DefaultEndpointName)
                    {
                        return 0;
                    }
                    return 1;
                })
                );

            ViewBag.WebServices = JsonConvert.SerializeObject(this._webServices);

            return View();
        }

        public ActionResult UploadData()
        {
            return View();
        }

        public ActionResult Retrain()
        {
            var file = Request.Files["fileToUpload"];

            AzureBlobDataReference blobReference;
            if (file!=null && file.ContentLength > 0)
            {
                // save file to blob
                blobReference = Helper.UploadFileToBlob(file.InputStream, file.FileName);
            }
            else
            {
                blobReference = new AzureBlobDataReference()
                {
                    ConnectionString = Configurations.AzureStorageConnectionString,
                    RelativeLocation =
                        Configurations.AzureStorageContainerName + "/" + Configurations.AzureStoragePreUploadedBlobName
                };
            }

            // get endpoint name and webservice id from cookie
            var webserviceId = Request.Cookies["webService_train"].Value;
            var endpointName = Request.Cookies["endpoint_train"].Value;
            var webService = this._webServices.First(w => w.Id == webserviceId);
            var endpoint = webService.Endpoints.First(e => e.Name == endpointName);


           
            var request = new BatchRequest() { Input = blobReference };
            var id = endpoint.SubmitBatch(request).Result;

            // add job id and endpoint key to cookie
            var additionalCookie = new HttpCookie("jobId") { Value = id };
            Response.Cookies.Add(additionalCookie);
            var endpointKeyCookie = new HttpCookie("key") { Value = endpoint.PrimaryKey };
            Response.Cookies.Add(endpointKeyCookie);
            ViewBag.RequestUri = endpoint.ApiLocation + "/jobs/" + id + "?api-version=2.0";
            ViewBag.EndpointName = endpoint.Name;
            ViewBag.WebServiceName = webService.Name;
            ViewBag.JobId = id;
            return View();
        }


        public ActionResult GetRetrainResults()
        {
            // get endpoint name and webservice id from cookie
            var webserviceId = Request.Cookies["webService_train"].Value;
            var endpointName = Request.Cookies["endpoint_train"].Value;
            var endpoint = this._webServices.First(w => w.Id == webserviceId).Endpoints.First(e => e.Name == endpointName);
            var jobId = Request.Cookies["jobId"].Value;
            var job = endpoint.GetBatchStatus(jobId).Result;
            ViewBag.EvalLink = job.Results[Configurations.EvaluationOutputPortName].ToUri();
            return View();
        }

        public ActionResult SubmitUpdate()
        {
            var jobId = Request.Cookies["jobId"].Value;
            var trainingWebserviceId = Request.Cookies["webService_train"].Value;
            var trainingEndpointName = Request.Cookies["endpoint_train"].Value;
            var trainingEndpoint = this._webServices.First(w => w.Id == trainingWebserviceId).Endpoints.First(e => e.Name == trainingEndpointName);

            var webserviceId = Request.Cookies["webService_score"].Value;
            var endpointName = Request.Cookies["endpoint_score"].Value;
            var endpoint = this._webServices.First(w => w.Id == webserviceId).Endpoints.First(e => e.Name == endpointName);
            var job = trainingEndpoint.GetBatchStatus(jobId).Result;
            var successful = endpoint.UpdateResource(new ResourceLocations() { Resources = new[] { new EndpointResource() { Name = Configurations.ScoringResourceName, Location = job.Results[Configurations.TrainedModelOutputPortName] } } }).Result;
            if (successful)
            {
                ViewBag.Message = "Successfully updated endpoint " + endpointName;
            }
            else
            {
                ViewBag.Message = "failed to update endpoint " + endpointName;
            }
            return View();
        }

        public string QueryJobStatus(string jobId)
        {
            var webserviceId = Request.Cookies["webService_train"].Value;
            var endpointName = Request.Cookies["endpoint_train"].Value;
            var endpoint = this._webServices.First(w => w.Id == webserviceId).Endpoints.First(e => e.Name == endpointName);
            return JsonConvert.SerializeObject(endpoint.GetBatchStatus(jobId).Result.StatusCode.ToString());
        }
    }
}